package cn.magictodo.weblog.jwt.handler;

import com.github.jaemon.dinger.DingerSender;
import com.github.jaemon.dinger.core.entity.DingerRequest;
import com.github.jaemon.dinger.core.entity.enums.MessageSubType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

import static cn.magictodo.weblog.common.enums.RedisPrefixEnum.REDIS_QUIET_ACCESS_IP;

/**
 * 请求IP的处理
 *
 * @author liu
 * @since 2023-12-18 15:29
 */
@Slf4j
@Component
public class IPHandler {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private DingerSender dingerSender;

    /**处理ip是否允许登录
     *
     * @param request
     * @return
     */
    public  Boolean isLogin(HttpServletRequest request) {
        String ip = getRealIp(request);
        String redisSaveIp = REDIS_QUIET_ACCESS_IP.getPrefix()+ip;
        if(ip!=null){
            if(redisTemplate.hasKey(redisSaveIp)) {
                //如果该ip在有效时间内尝试多次，拒绝登录
                if ((Integer) redisTemplate.opsForValue().get(redisSaveIp) > 5){
                    dingerSender.send( MessageSubType.MARKDOWN, DingerRequest.request("IP:"+ip+"拒绝访问","IP封禁"));
                    return false;
                } else{
                    return true;
                }
            } else {
                return true;
            }

        }
        return false;
    }

    /**
     * 判断真实IP
     */
    public String getRealIp(HttpServletRequest request) {

//        Enumeration<String> headerNames = request.getHeaderNames();
//
//        while (headerNames.hasMoreElements()) {
//            String headerName = headerNames.nextElement();
//            String headerValue = request.getHeader(headerName);
//            log.info("请求头"+headerName + ": " + headerValue);
//        }
             String ip = request.getHeader("X-Real-IP");
        //判断真实ip
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
             ip = request.getHeader("x-forwarded-for");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
           ip = request.getHeader("HTTP_CLIENT_IP");
        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        log.info("请求IP地址：" + ip);
        //ip分割处理
        ip = extractFirstIpAddress(ip);

        return ip;
    }

    /**
     * 登录失败，记录ip
     * @param request
     * @return
     */
    public String failLogin(HttpServletRequest request) {
//        1.获取ip
        String realIp = getRealIp(request);
        String redisSaveIp = REDIS_QUIET_ACCESS_IP.getPrefix()+realIp;
        if (realIp!= null) {
            if(redisTemplate.hasKey(redisSaveIp)) {
                log.info("已经登录错误=======================");
//                如果有该ip记录，则设置+1
                redisTemplate.opsForValue().increment(redisSaveIp);
                redisTemplate.expire(redisSaveIp, 3, TimeUnit.MINUTES);
            } else {
                log.info("已经登录错误=======================");
//                如果没有，则设置为1
                redisTemplate.opsForValue().set(redisSaveIp, 1,3, TimeUnit.MINUTES);
            }
        }
        return null;
    }

    /**
     * 取第一个ip地址
     * @param input
     * @return
     */
    private static String extractFirstIpAddress(String input) {
        String[] ipAddresses = input.split(",\\s*");
        if (ipAddresses.length > 0) {
            return ipAddresses[0];
        }
        return null;
    }


}
